/*
 * To change this template, choose Tools | Templates and open the template in
 * the editor.
 */
package org.exes;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;

/**
 *
 * @author odeen
 */
public class NIO {

    public static void copiar(File origen, File destino) throws FileNotFoundException, IOException {
        if (origen.isDirectory()) {
            if (!destino.exists()) {
                destino.mkdirs();
                destino.setLastModified(origen.lastModified());
            }
            String[] hijos = origen.list();
            for (int i = 0; i < hijos.length; i++) {
                copiar(new File(origen, hijos[i]), new File(destino, hijos[i]));
            }
        } else {
            copiarFichero(origen, destino);
        }
    }

    private static void copiarFichero(File origen, File destino) throws FileNotFoundException, IOException {
        FileInputStream fis = new FileInputStream(origen);
        FileOutputStream fos = new FileOutputStream(destino);
        FileChannel canalFuente = fis.getChannel();
        FileChannel canalDestino = fos.getChannel();
        canalFuente.transferTo(0, canalFuente.size(), canalDestino);
        fos.flush();
        fis.close();
        fos.close();
        destino.setLastModified(origen.lastModified());
    }

    public static void copiarFicheroAFlujo(File origen, OutputStream os) throws FileNotFoundException, IOException {
        FileInputStream fis = new FileInputStream(origen);
        FileChannel canalFuente = fis.getChannel();
        WritableByteChannel canalDestino = Channels.newChannel(os);
        canalFuente.transferTo(0, canalFuente.size(), canalDestino);
        os.flush();
        fis.close();
    }

    public static void copiarFlujoAFichero(InputStream is, File fichero) throws FileNotFoundException, IOException {
        FileOutputStream fos = new FileOutputStream(fichero);
        FileChannel canalDestino = fos.getChannel();
        ReadableByteChannel canalFuente = Channels.newChannel(is);
        canalDestino.transferFrom(canalFuente, 0, is.available());
        fos.flush();
        fos.close();
    }

    public static void copiarFlujoAFichero(long tamaño, InputStream is, File fichero) throws FileNotFoundException, IOException {
        FileOutputStream fos = new FileOutputStream(fichero);
        FileChannel canalDestino = fos.getChannel();
        ReadableByteChannel canalFuente = Channels.newChannel(is);
        long leido = 0;
        while (tamaño > 0) {
            leido = canalDestino.transferFrom(canalFuente, 0, tamaño);
            tamaño -= leido;
        }
        fos.flush();
        fos.close();
    }

    public static void copiarFlujoAFlujo(long tamaño, InputStream is, OutputStream os) throws FileNotFoundException, IOException {
        WritableByteChannel canalDestino = Channels.newChannel(os);
        ReadableByteChannel canalFuente = Channels.newChannel(is);
        ByteBuffer buffer = ByteBuffer.allocate(64 * 1024);
        if (tamaño == -1) {
            int leido = Integer.MAX_VALUE;
            while (leido > 0) {
                leido = canalFuente.read(buffer);
                if (leido > 0) {
                    buffer.flip();
                    canalDestino.write(buffer);
                    buffer.clear();
                }
            }
        } else {
            do {
                tamaño -= canalFuente.read(buffer);
                buffer.flip();
                canalDestino.write(buffer);
                buffer.clear();
            } while (tamaño > 0);
        }
        os.flush();
    }
}
